/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package kimo.bl;

import java.util.Date;
import java.util.Set;
import kimo.persistence.controllers.exceptions.NonexistentEntityException;
import kimo.persistence.entities.Product;
import kimo.persistence.entities.ProductCategory;
import kimo.persistence.entities.ProductType;
import kimo.persistence.entities.Production;
import kimo.persistence.entities.RawProduct;
import kimo.persistence.entities.RawProductType;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.ForwardEvent;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zul.Button;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Div;
import org.zkoss.zul.Doublebox;
import org.zkoss.zul.Grid;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Textbox;

/**
 *
 * @author a381u296
 */
public class ProdProduction extends KimoUI {

    @Wire
    Div production_div;
    @Wire
    Listbox production;
    @Wire
    Grid production_editable_grid;
    @Wire
    Textbox production_farm_osde;
    @Wire
    Doublebox production_farm_area;

    @Wire
    Listbox production_raw_product_type;

    @Wire
    Listbox production_raw_product;
    @Wire
    Doublebox production_raw_product_kilos;
    @Wire
    Listbox production_product_category;
    @Wire
    Listbox production_product_type;
    @Wire
    Combobox production_product;
    @Wire
    Doublebox production_product_kilos;

    private ListModelList<Production> lmlProductions;
    private ListModelList<RawProductType> lmlRawProductType;
    private ListModelList<RawProduct> lmlRawProduct;
    private ListModelList<ProductCategory> lmlProductCategory;
    private ListModelList<ProductType> lmlProductType;
    private ListModelList<Product> lmlProduct;
    private boolean new_production;
    private Production productionItem;

    @Override
    public void doAfterCompose(Component comp) throws Exception {
        super.doAfterCompose(comp); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    void getFromUI() {
        productionItem.setProductionFarmOsde(production_farm_osde.getValue());
        productionItem.setProductionFarmArea(production_farm_area.getValue());
        RawProduct rawProduct = lmlRawProduct.getSelection().iterator().next();
        productionItem.setProductionRawProductId(rawProduct);
        productionItem.setProductionRawProductKilos(production_raw_product_kilos.getValue());
        Product product = lmlProduct.getSelection().iterator().next();
        productionItem.setProductionProductId(product);
        productionItem.setProductionProductKilos(production_product_kilos.getValue());
    }

    @Override
    void updateUI() {

        // ΠΡΟΣΟΧΗ αυτη να αφορα στο αρχικο μονο listbox
    }

    void updateGridUI() {
        production_farm_osde.setValue(productionItem.getProductionFarmOsde());
        production_farm_area.setValue(productionItem.getProductionFarmArea());
        production_raw_product_kilos.setValue(productionItem.getProductionRawProductKilos());
        production_product_kilos.setValue(productionItem.getProductionProductKilos());

        // 1. ΒΑΖΩ ΤΗΝ ΛΙΣΤΑ ΣΤΟ LIST MODEL
        lmlRawProductType = new ListModelList<RawProductType>(getKdao().
                getRawProductTypes());
        // 2. ΠΑΙΡΝΩ ΤΟ ΙΤΕΜ ΘΕΛΩ ΓΙΑ SELECTED
        RawProductType rawProductType = productionItem.getProductionRawProductTypeId();
        // 3. ΒΑΖΩ ΣΤΟ SELECTION ΤΟΥ LISTMODEL
        lmlRawProductType.addToSelection(rawProductType);
        // 4. ΚΟΥΜΠΩΝΩ LIST MODEL ΜΕ LIST BOX
        production_raw_product_type.setModel(lmlRawProductType);

        // 1. ΒΑΖΩ ΤΗΝ ΛΙΣΤΑ ΣΤΟ LIST MODEL
        lmlRawProduct = new ListModelList<RawProduct>(rawProductType.getRawProductList());
        // 2. ΠΑΙΡΝΩ ΤΟ ΙΤΕΜ ΘΕΛΩ ΓΙΑ SELECTED
        RawProduct rawProduct = productionItem.getProductionRawProductId();
        // 3. ΒΑΖΩ ΣΤΟ SELECTION ΤΟΥ LISTMODEL
        lmlRawProduct.addToSelection(rawProduct);
        // 4. ΚΟΥΜΠΩΝΩ LIST MODEL ΜΕ LIST BOX
        production_raw_product.setModel(lmlRawProduct);

        // 1. ΒΑΖΩ ΤΗΝ ΛΙΣΤΑ ΣΤΟ LIST MODEL
        lmlProductCategory = new ListModelList<ProductCategory>(getKdao().getProductCategories());
        // 2. ΠΑΙΡΝΩ ΤΟ ΙΤΕΜ ΘΕΛΩ ΓΙΑ SELECTED
        ProductCategory productCategory = productionItem.getProductionProductCategoryId();
        // 3. ΒΑΖΩ ΣΤΟ SELECTION ΤΟΥ LISTMODEL
        lmlProductCategory.addToSelection(productCategory);
        // 4. ΚΟΥΜΠΩΝΩ LIST MODEL ΜΕ LIST BOX
        production_product_category.setModel(lmlProductCategory);

        // 1. ΒΑΖΩ ΤΗΝ ΛΙΣΤΑ ΣΤΟ LIST MODEL
        lmlProductType = new ListModelList<ProductType>(productCategory.getProductTypeList());
        // 2. ΠΑΙΡΝΩ ΤΟ ΙΤΕΜ ΘΕΛΩ ΓΙΑ SELECTED
        ProductType productType = productionItem.getProductionProductTypeId();
        // 3. ΒΑΖΩ ΣΤΟ SELECTION ΤΟΥ LISTMODEL
        lmlProductType.addToSelection(productType);
        // 4. ΚΟΥΜΠΩΝΩ LIST MODEL ΜΕ LIST BOX
        production_product_type.setModel(lmlProductType);

        // 1. ΒΑΖΩ ΤΗΝ ΛΙΣΤΑ ΣΤΟ LIST MODEL
        lmlProduct = new ListModelList<Product>(productType.getProductList());
        // 2. ΠΑΙΡΝΩ ΤΟ ΙΤΕΜ ΘΕΛΩ ΓΙΑ SELECTED
        Product product = productionItem.getProductionProductId();
        // 3. ΒΑΖΩ ΣΤΟ SELECTION ΤΟΥ LISTMODEL
        lmlProduct.addToSelection(product);
        // 4. ΚΟΥΜΠΩΝΩ LIST MODEL ΜΕ LIST BOX
        production_product.setModel(lmlProduct);

    }

    @Override
    void clearUI() {
        production_farm_osde.setRawValue("");
        production_farm_area.setRawValue("");
        production_raw_product_kilos.setRawValue("");
        production_product_kilos.setRawValue("");
        production_product.setRawValue("");
    }

    @Override
    void populateListboxs() {
        // εδω θα κουμπωσω μονο τα αρχικο list
        // αν πατησει ΠΡΟΣΘΗΚΗ ή ΕΠΕΞΕΡΓΑΣΙΑ θα γεμισω και τα υπολοιπα 
        //lmlProductions.clear();
        lmlProductions = new ListModelList<Production>(getKdao()
                .getProducerProductions());
        production.setModel(lmlProductions);

    }

    void populateGridListboxs() {
        // τα γεμιζω με τις πρωτες επιλογες, ειναι για εισαγωγη

        lmlRawProductType = new ListModelList<RawProductType>(getKdao().
                getRawProductTypes());
        production_raw_product_type.setModel(lmlRawProductType);
        RawProductType rawProductType = lmlRawProductType.getInnerList().iterator().next();
        lmlRawProductType.addToSelection(rawProductType);

        lmlRawProduct = new ListModelList<RawProduct>(rawProductType.getRawProductList());
        production_raw_product.setModel(lmlRawProduct);

        RawProduct rawProduct = lmlRawProduct.getInnerList().iterator().next();
        lmlRawProduct.addToSelection(rawProduct);

        lmlProductCategory = new ListModelList<ProductCategory>(getKdao().getProductCategories());
        production_product_category.setModel(lmlProductCategory);
        ProductCategory productCategory = lmlProductCategory.getInnerList().iterator().next();
        lmlProductCategory.addToSelection(productCategory);

        lmlProductType = new ListModelList<ProductType>(productCategory.getProductTypeList());
        production_product_type.setModel(lmlProductType);
        ProductType productType = lmlProductType.getInnerList().iterator().next();
        lmlProductType.addToSelection(productType);

        lmlProduct = new ListModelList<Product>(productType.getProductList());
        production_product.setModel(lmlProduct);

    }

    @Listen("onSelect = #production_raw_product_type")
    public void onProductionRawProductTypeSelect() {
        Set<RawProductType> rawProductTypes = lmlRawProductType.getSelection();
        RawProductType rawProductType = rawProductTypes.iterator().next();
        lmlRawProduct = new ListModelList<RawProduct>(getKdao().getRawProducts(rawProductType));
        production_raw_product.setModel(lmlRawProduct);
        RawProduct next = lmlRawProduct.getInnerList().iterator().next();
        lmlRawProduct.addToSelection(next);
    }

    @Listen("onSelect = #production_product_category")
    public void onProductionProductCategorySelect() {
        Set<ProductCategory> productCategories = lmlProductCategory.getSelection();
        ProductCategory productCategory = productCategories.iterator().next();

        lmlProductType = new ListModelList<ProductType>(productCategory.getProductTypeList());
        ProductType productType = lmlProductType.getInnerList().iterator().next();
        lmlProductType.addToSelection(productType);
        production_product_type.setModel(lmlProductType);

        lmlProduct = new ListModelList<Product>(productType.getProductList());
        production_product.setModel(lmlProduct);
    }

    @Listen("onSelect = #production_product_type")
    public void onProductionProductTypeSelect() {
        Set<ProductType> productTypes = lmlProductType.getSelection();
        ProductType productType = productTypes.iterator().next();
        lmlProduct = new ListModelList<Product>(getKdao().getProduct(productType));
        production_product.setModel(lmlProduct);
        production_product.setText("");
    }

    @Listen("onClick = #saveProductionBtn")
    public void onSaveProductionBtn() throws Exception {
        if (new_production) {
            // εισαγουμε εγγραφη
            productionItem = new Production();
            checkProduct();
            getFromUI();
            productionItem.setProductionYear(new Date());
            getKdao().saveNewProduction(productionItem);
            lmlProductions.add(productionItem);
            Messagebox.show("Η εγγραφή καταχωρήθηκε !");

            production_editable_grid.setVisible(false);
            production_div.setVisible(true);
        } else {
            checkProduct();
            getFromUI();
            getKdao().editProduction(productionItem);

            Messagebox.show("H εγγραφή ενημερώθηκε !");
            populateListboxs();
            production_editable_grid.setVisible(false);
            production_div.setVisible(true);
        }
    }

    @Listen("onClick = #insertProductionBtn")
    public void onInsertProductionBtnClick() {
        production_editable_grid.setVisible(true);
        new_production = true;
        production_div.setVisible(false);
        populateGridListboxs();
        clearUI();
    }

    @Listen("onClick = #cancelProductionBtn")
    public void onCancelProductionBtn() {
        production_editable_grid.setVisible(false);
        production_div.setVisible(true);
        productionItem = null;
        clearUI();
    }

    @Listen("onBlur = #production_farm_osde")
    public void onProductionFarmOsdeBlur() {
        String osde = production_farm_osde.getValue();
        if (osde.equals("")) {
            production_farm_osde.setValue("ΛΑΧΑΝΟΚΗΠΟΣ");
        }

    }

    @Listen("onBlur = #production_farm_area")
    public void onProductionFarmAreaBlur() {
        String osde = production_farm_osde.getValue();
        if (osde.equals("")) {
            production_farm_osde.setValue("ΛΑΧΑΝΟΚΗΠΟΣ");
        }
        osde = production_farm_osde.getValue();
        Double area = production_farm_area.getValue();
        if (osde.equals("ΛΑΧΑΝΟΚΗΠΟΣ") && (area > 1)) {
            throw new WrongValueException(production_farm_area, "Μεγαλη εκταση για οικιακο λαχανόκηπο !!! Πρεπει να ειναι λιγοτερη απο 1 !");
        }
    }

    private void checkProduct() {
        if (lmlProduct.isSelectionEmpty()) {

            // υποθετω οτι εχει γραψει κατι, 
            // αλλιως η gettext θα πεταξει Wrong Value Exception
            Product product = new Product();
            product.setProductName(production_product.getText());
            product.setProductTypeId(lmlProductType.getSelection().iterator().next());
            getKdao().saveProduct(product);
            lmlProduct.add(product);
            lmlProduct.addToSelection(product);
        }
    }

    @Listen("onSelect = #production")
    public void onProductionSelect() {
        productionItem = lmlProductions.getSelection().iterator().next();
        new_production = false;
        production_div.setVisible(false);

        production_editable_grid.setVisible(true);
        updateGridUI();

    }

    @Listen("onEdit = #production")
    public void onProductionEdit(ForwardEvent evt) {
        Button btn = (Button) evt.getOrigin().getTarget();
        Listitem litem = (Listitem) btn.getParent().getParent();

        productionItem = (Production) litem.getValue();

        new_production = false;
        production_div.setVisible(false);

        production_editable_grid.setVisible(true);
        updateGridUI();
    }

    @Listen("onDelete = #production")
    public void removeProduction(ForwardEvent evt) throws NonexistentEntityException {

        Button btn = (Button) evt.getOrigin().getTarget();
        Listitem litem = (Listitem) btn.getParent().getParent();

        productionItem = (Production) litem.getValue();

        getKdao().deleteProduction(productionItem);

       
        production_editable_grid.setVisible(false);
        production_div.setVisible(true);
        Messagebox.show("Η εγγραφή Διαγράφτηκε");
       
        lmlProductions.clear();
        populateListboxs();

    }

    
    
    
}
